package com.blog.config;

import com.blog.entity.Users;
import com.blog.mapper.UsersMapper;
import com.blog.service.UsersService;
import com.blog.utils.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.blog.utils.Staticmessage.USERSNOTEXIST;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private UsersMapper usersMapper;
    //需要手动向外面暴露，用于登录的时候的认证
    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager(); // 从 Spring 容器获取
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
//                .cors(Customizer.withDefaults())
                .csrf(csrf -> csrf.disable()) // 禁用 CSRF（适用于 JWT）
                .authorizeHttpRequests(authorize -> authorize // 使用新版 authorizeHttpRequests
                        .antMatchers("/public/user/**").permitAll() // 放行登录接口
                        .antMatchers(HttpMethod.OPTIONS).permitAll()
                        .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // 用户和管理员可访问
                        .antMatchers("/admin/**").hasRole("ADMIN") // 仅管理员可访问


                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话
                )
                .addFilterBefore(
                        new JwtAuthenticationFilter(jwtTokenProvider),
                        UsernamePasswordAuthenticationFilter.class
                );

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 密码加密方式
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
//        config.setAllowedOrigins(Collections.singletonList("http://localhost:5173")); // 允许的前端地址
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        config.setAllowCredentials(true); // 允许 Cookie

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 全局生效
        return source;
    }

    @Bean
    public UserDetailsService loadUserByUsername() {
        return email -> { // Lambda 表达式实现 UserDetailsService
            Users user = usersMapper.findByEmail(email);
            if (user == null) {
                throw new UsernameNotFoundException(USERSNOTEXIST);
            }

            List<GrantedAuthority> authorities = new ArrayList<>();
            if (user.getRole() == 1) {
                authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); // 注意添加ROLE_前缀
                authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            } else if (user.getRole() == 2) {
                authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            }

            return new org.springframework.security.core.userdetails.User(
                    user.getEmail(),
                    user.getPassword(),
                    user.getRole() != 0, // 是否启用（role=0表示禁用）
                    true, true, true,    // 账号是否未过期、凭证是否未过期、账号是否未锁定
                    authorities
            );
        };

    }

}